<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>网球场样式自定义器</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Arial', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(45deg, #2196F3, #21CBF3);
            color: white;
            padding: 20px;
            text-align: center;
        }

        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }

        .controls {
            padding: 30px;
            background: #f8f9fa;
            border-bottom: 1px solid #e9ecef;
        }

        .control-group {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin-bottom: 20px;
        }

        .control-item {
            flex: 1;
            min-width: 200px;
        }

        .control-item label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
            color: #333;
        }

        .control-item input, .control-item select {
            width: 100%;
            padding: 10px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            transition: border-color 0.3s;
        }

        .control-item input:focus, .control-item select:focus {
            outline: none;
            border-color: #2196F3;
        }

        .color-input {
            height: 50px;
            cursor: pointer;
        }

        .court-area {
            padding: 30px;
            background: white;
            min-height: 600px;
            position: relative;
        }

        .court-container {
            display: flex;
            flex-wrap: wrap;
            gap: 1px;
            justify-content: flex-start;
            align-items: center;
            border: 2px dashed #ddd;
            border-radius: 10px;
            padding: 20px;
            position: relative;
        }

        .tennis-court {
            width: 60px;
            height: 100px;
            /* border-radius: 8px; */
            position: relative;
            cursor: move;
            transition: transform 0.2s, box-shadow 0.2s;
            user-select: none;
            padding: 8px;
            margin: 5px;
        }

        .tennis-court:hover {
            transform: scale(1.05);
            box-shadow: 0 5px 15px rgba(0,0,0,0.3);
        }

        .tennis-court.dragging {
            opacity: 0.7;
            transform: rotate(5deg);
            z-index: 1000;
        }

        .court-lines {
            position: absolute;
            top: 8px;
            left: 8px;
            right: 8px;
            bottom: 8px;
            border: 2px solid white;
            background: inherit;
        }

        .net-line {
            position: absolute;
            top: 50%;
            left: 0;
            right: 0;
            height: 2px;
            background: white;
            transform: translateY(-50%);
        }

        .service-line {
            position: absolute;
            top: 25%;
            left: 0;
            right: 0;
            height: 1px;
            background: white;
        }

        .service-line.bottom {
            top: 75%;
        }

        .center-line {
            position: absolute;
            top: 25%;
            left: 50%;
            bottom: 25%;
            width: 1px;
            background: white;
            transform: translateX(-50%);
        }

        .view-controls {
            position: absolute;
            top: 20px;
            right: 20px;
            display: flex;
            gap: 10px;
        }

        .view-btn {
            padding: 10px 15px;
            background: #2196F3;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background 0.3s;
        }

        .view-btn:hover {
            background: #1976D2;
        }

        .view-btn.active {
            background: #4CAF50;
        }

        .top-view {
            transform: perspective(800px) rotateX(60deg);
        }

        .generate-btn {
            width: 100%;
            padding: 12px;
            background: linear-gradient(45deg, #FF6B6B, #FF8E53);
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s;
            margin-top: 10px;
        }

        .generate-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4);
        }

        .code-modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.8);
            z-index: 10000;
            justify-content: center;
            align-items: center;
        }

        .code-content {
            background: white;
            padding: 20px;
            border-radius: 10px;
            max-width: 90%;
            max-height: 80%;
            overflow: auto;
            position: relative;
        }

        .code-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .code-title {
            font-size: 18px;
            font-weight: bold;
            color: #333;
        }

        .close-btn {
            background: #f44336;
            color: white;
            border: none;
            border-radius: 50%;
            width: 30px;
            height: 30px;
            cursor: pointer;
            font-size: 16px;
        }

        .code-output {
            background: #f5f5f5;
            border: 1px solid #ddd;
            border-radius: 5px;
            padding: 15px;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            white-space: pre-wrap;
            word-break: break-all;
            max-height: 400px;
            overflow-y: auto;
        }

        .copy-btn {
            background: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            padding: 8px 16px;
            cursor: pointer;
            margin-top: 10px;
        }

        .copy-btn:hover {
            background: #45a049;
        }

        .info-panel {
            position: absolute;
            bottom: 20px;
            left: 20px;
            background: rgba(0,0,0,0.8);
            color: white;
            padding: 15px;
            border-radius: 8px;
            font-size: 14px;
        }

        @media (max-width: 768px) {
            .control-group {
                flex-direction: column;
            }
            
            .control-item {
                min-width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🎾 网球场样式自定义器</h1>
            <p>自定义您的网球场样式，支持拖拽和俯瞰图视角</p>
        </div>

        <div class="controls">
            <div class="control-group">
                <div class="control-item">
                    <label for="courtCount">球场数量:</label>
                    <input type="number" id="courtCount" min="1" max="20" value="4">
                </div>
                <div class="control-item">
                    <label for="arrangement">排列方式:</label>
                    <select id="arrangement">
                        <option value="grid">网格排列</option>
                        <option value="horizontal">水平排列</option>
                        <option value="vertical">垂直排列</option>
                        <option value="circular">圆形排列</option>
                    </select>
                </div>
                <div class="control-item">
                    <button id="generateCode" class="generate-btn">生成HTML代码</button>
                </div>
            </div>
            <div class="control-group" id="colorControls">
                <!-- 每个球场的颜色控制将在这里动态生成 -->
            </div>
        </div>

        <div class="court-area">
            <div class="view-controls">
                <button class="view-btn active" data-view="normal">普通视图</button>
                <button class="view-btn" data-view="top">俯瞰图</button>
            </div>
            
            <div class="court-container" id="courtContainer">
                <!-- 网球场将在这里动态生成 -->
            </div>
            
            <div class="info-panel">
                <div>球场数量: <span id="courtCountDisplay">4</span></div>
                <div>排列方式: <span id="arrangementDisplay">网格排列</span></div>
                <div>视图模式: <span id="viewDisplay">普通视图</span></div>
                <div>提示: 拖拽球场可以重新排列位置</div>
            </div>
        </div>

        <!-- 代码生成模态框 -->
        <div class="code-modal" id="codeModal">
            <div class="code-content">
                <div class="code-header">
                    <div class="code-title">生成的HTML代码</div>
                    <button class="close-btn" id="closeModal">×</button>
                </div>
                <div class="code-output" id="codeOutput"></div>
                <button class="copy-btn" id="copyCode">复制代码</button>
            </div>
        </div>
    </div>

    <script>
        class TennisCourtCustomizer {
            constructor() {
                this.courtContainer = document.getElementById('courtContainer');
                this.courtCountInput = document.getElementById('courtCount');
                this.arrangementSelect = document.getElementById('arrangement');
                this.viewButtons = document.querySelectorAll('.view-btn');
                this.colorControls = document.getElementById('colorControls');
                
                this.courtCountDisplay = document.getElementById('courtCountDisplay');
                this.arrangementDisplay = document.getElementById('arrangementDisplay');
                this.viewDisplay = document.getElementById('viewDisplay');
                this.generateBtn = document.getElementById('generateCode');
                this.codeModal = document.getElementById('codeModal');
                this.codeOutput = document.getElementById('codeOutput');
                this.closeModal = document.getElementById('closeModal');
                this.copyCode = document.getElementById('copyCode');
                
                this.currentView = 'normal';
                this.draggedElement = null;
                this.offset = { x: 0, y: 0 };
                this.courtColors = []; // 存储每个球场的颜色设置
                
                this.init();
            }
            
            init() {
                this.createCourts();
                this.bindEvents();
            }
            
            bindEvents() {
                // 数量变化事件
                this.courtCountInput.addEventListener('input', () => this.updateCourtCount());
                
                // 排列方式变化事件
                this.arrangementSelect.addEventListener('change', () => this.updateArrangement());
                
                // 视图切换事件
                this.viewButtons.forEach(btn => {
                    btn.addEventListener('click', (e) => this.switchView(e.target.dataset.view));
                });
                
                // 生成代码事件
                this.generateBtn.addEventListener('click', () => this.generateHTMLCode());
                this.closeModal.addEventListener('click', () => this.closeCodeModal());
                this.copyCode.addEventListener('click', () => this.copyToClipboard());
            }
            
            createCourts() {
                const count = parseInt(this.courtCountInput.value);
                this.courtContainer.innerHTML = '';
                
                // 初始化颜色数组
                this.courtColors = [];
                for (let i = 0; i < count; i++) {
                    this.courtColors.push({
                        courtColor: '#4CAF50',
                        outsideColor: '#8BC34A'
                    });
                }
                
                for (let i = 0; i < count; i++) {
                    const court = this.createCourt(i);
                    this.courtContainer.appendChild(court);
                }
                
                this.createColorControls();
                this.updateArrangement();
                this.updateCourtColors();
            }
            
            createCourt(index) {
                const court = document.createElement('div');
                court.className = 'tennis-court';
                court.draggable = true;
                court.dataset.index = index;
                
                court.innerHTML = `
                    <div class="court-lines">
                        <div class="net-line"></div>
                        <div class="service-line"></div>
                        <div class="service-line bottom"></div>
                        <div class="center-line"></div>
                    </div>
                `;
                
                // 添加拖拽事件
                court.addEventListener('dragstart', (e) => this.handleDragStart(e));
                court.addEventListener('dragend', (e) => this.handleDragEnd(e));
                court.addEventListener('dragover', (e) => this.handleDragOver(e));
                court.addEventListener('drop', (e) => this.handleDrop(e));
                
                return court;
            }
            
            updateCourtColors() {
                const courts = this.courtContainer.querySelectorAll('.tennis-court');
                
                courts.forEach((court, index) => {
                    const colors = this.courtColors[index];
                    court.style.backgroundColor = colors.outsideColor;
                    const courtLines = court.querySelector('.court-lines');
                    courtLines.style.backgroundColor = colors.courtColor;
                });
            }
            
            createColorControls() {
                this.colorControls.innerHTML = '';
                const count = parseInt(this.courtCountInput.value);
                
                for (let i = 0; i < count; i++) {
                    const controlGroup = document.createElement('div');
                    controlGroup.className = 'control-item';
                    controlGroup.style.flex = '1';
                    controlGroup.style.minWidth = '200px';
                    
                    controlGroup.innerHTML = `
                        <label>球场 ${i + 1} 颜色:</label>
                        <div style="display: flex; gap: 10px; align-items: center;">
                            <div style="flex: 1;">
                                <label style="font-size: 12px; margin-bottom: 4px;">场内:</label>
                                <input type="color" class="color-input court-color-input" data-court="${i}" data-type="courtColor" value="${this.courtColors[i].courtColor}">
                            </div>
                            <div style="flex: 1;">
                                <label style="font-size: 12px; margin-bottom: 4px;">场外:</label>
                                <input type="color" class="color-input outside-color-input" data-court="${i}" data-type="outsideColor" value="${this.courtColors[i].outsideColor}">
                            </div>
                        </div>
                    `;
                    
                    this.colorControls.appendChild(controlGroup);
                }
                
                // 绑定颜色变化事件
                this.colorControls.querySelectorAll('.color-input').forEach(input => {
                    input.addEventListener('input', (e) => {
                        const courtIndex = parseInt(e.target.dataset.court);
                        const colorType = e.target.dataset.type;
                        this.courtColors[courtIndex][colorType] = e.target.value;
                        this.updateCourtColors();
                    });
                });
            }
            
            updateCourtCount() {
                const count = parseInt(this.courtCountInput.value);
                this.courtCountDisplay.textContent = count;
                this.createCourts();
            }
            
            updateArrangement() {
                const arrangement = this.arrangementSelect.value;
                const courts = this.courtContainer.querySelectorAll('.tennis-court');
                
                this.arrangementDisplay.textContent = this.arrangementSelect.options[this.arrangementSelect.selectedIndex].text;
                
                // 重置样式
                this.courtContainer.style.display = 'flex';
                this.courtContainer.style.flexDirection = 'row';
                this.courtContainer.style.justifyContent = 'center';
                this.courtContainer.style.alignItems = 'center';
                
                courts.forEach(court => {
                    court.style.position = 'relative';
                    court.style.margin = '5px';
                });
                
                switch (arrangement) {
                    case 'horizontal':
                        this.courtContainer.style.flexWrap = 'nowrap';
                        break;
                    case 'vertical':
                        this.courtContainer.style.flexDirection = 'column';
                        this.courtContainer.style.flexWrap = 'nowrap';
                        break;
                    case 'circular':
                        this.arrangeCircularly(courts);
                        break;
                    default: // grid
                        this.courtContainer.style.flexWrap = 'wrap';
                }
            }
            
            arrangeCircularly(courts) {
                const containerRect = this.courtContainer.getBoundingClientRect();
                const centerX = containerRect.width / 2;
                const centerY = containerRect.height / 2;
                const radius = Math.min(centerX, centerY) - 100;
                
                courts.forEach((court, index) => {
                    const angle = (index / courts.length) * 2 * Math.PI;
                    const x = centerX + radius * Math.cos(angle) - 60; // 60 is half of court width
                    const y = centerY + radius * Math.sin(angle) - 100; // 100 is half of court height
                    
                    court.style.position = 'absolute';
                    court.style.left = x + 'px';
                    court.style.top = y + 'px';
                    court.style.margin = '0';
                });
            }
            
            switchView(view) {
                this.currentView = view;
                
                // 更新按钮状态
                this.viewButtons.forEach(btn => {
                    btn.classList.toggle('active', btn.dataset.view === view);
                });
                
                // 更新显示文本
                this.viewDisplay.textContent = view === 'top' ? '俯瞰图' : '普通视图';
                
                // 应用视图样式
                if (view === 'top') {
                    this.courtContainer.classList.add('top-view');
                } else {
                    this.courtContainer.classList.remove('top-view');
                }
            }
            
            generateHTMLCode() {
                const count = parseInt(this.courtCountInput.value);
                const arrangement = this.arrangementSelect.value;
                
                let html = '<div style="display: flex; flex-wrap: wrap; gap: 5px; justify-content: flex-start; align-items: center; border: 2px dashed #ddd; border-radius: 10px; padding: 20px; position: relative;';
                
                if (arrangement === 'horizontal') {
                    html += ' flex-wrap: nowrap;';
                } else if (arrangement === 'vertical') {
                    html += ' flex-direction: column; flex-wrap: nowrap;';
                }
                
                html += '">';
                
                for (let i = 0; i < count; i++) {
                    const colors = this.courtColors[i];
                    let courtStyle = 'width: 60px; height: 100px; position: relative; cursor: move; transition: transform 0.2s, box-shadow 0.2s; user-select: none; padding: 8px; background-color: ' + colors.outsideColor + '; border-radius: 8px;';
                    
                    if (arrangement === 'circular') {
                        const angle = (i / count) * 2 * Math.PI;
                        const radius = 150;
                        const x = 200 + radius * Math.cos(angle) - 30;
                        const y = 200 + radius * Math.sin(angle) - 50;
                        courtStyle += ' position: absolute; left: ' + x + 'px; top: ' + y + 'px; margin: 0;';
                    } else {
                        courtStyle += ' margin: 5px;';
                    }
                    
                    html += '\n    <div style="' + courtStyle + '">';
                    html += '\n        <div style="position: absolute; top: 8px; left: 8px; right: 8px; bottom: 8px; border: 2px solid white; background-color: ' + colors.courtColor + '; border-radius: 4px;">';
                    html += '\n            <div style="position: absolute; top: 50%; left: 0; right: 0; height: 2px; background: white; transform: translateY(-50%);"></div>';
                    html += '\n            <div style="position: absolute; top: 25%; left: 0; right: 0; height: 1px; background: white;"></div>';
                    html += '\n            <div style="position: absolute; top: 75%; left: 0; right: 0; height: 1px; background: white;"></div>';
                    html += '\n            <div style="position: absolute; top: 25%; left: 50%; bottom: 25%; width: 1px; background: white; transform: translateX(-50%);"></div>';
                    html += '\n        </div>';
                    html += '\n    </div>';
                }
                
                html += '\n</div>';
                
                this.codeOutput.textContent = html;
                this.codeModal.style.display = 'flex';
            }
            
            closeCodeModal() {
                this.codeModal.style.display = 'none';
            }
            
            copyToClipboard() {
                const codeText = this.codeOutput.textContent;
                navigator.clipboard.writeText(codeText).then(() => {
                    alert('代码已复制到剪贴板！');
                }).catch(() => {
                    // 备用复制方法
                    const textArea = document.createElement('textarea');
                    textArea.value = codeText;
                    document.body.appendChild(textArea);
                    textArea.select();
                    document.execCommand('copy');
                    document.body.removeChild(textArea);
                    alert('代码已复制到剪贴板！');
                });
            }
            
            handleDragStart(e) {
                this.draggedElement = e.target;
                e.target.classList.add('dragging');
                
                const rect = e.target.getBoundingClientRect();
                this.offset.x = e.clientX - rect.left;
                this.offset.y = e.clientY - rect.top;
                
                e.dataTransfer.effectAllowed = 'move';
                e.dataTransfer.setData('text/html', e.target.innerHTML);
            }
            
            handleDragEnd(e) {
                e.target.classList.remove('dragging');
                this.draggedElement = null;
            }
            
            handleDragOver(e) {
                e.preventDefault();
                e.dataTransfer.dropEffect = 'move';
            }
            
            handleDrop(e) {
                e.preventDefault();
                
                if (this.draggedElement && e.target.classList.contains('tennis-court') && e.target !== this.draggedElement) {
                    // 交换位置
                    const container = this.courtContainer;
                    const draggedIndex = Array.from(container.children).indexOf(this.draggedElement);
                    const targetIndex = Array.from(container.children).indexOf(e.target);
                    
                    if (draggedIndex < targetIndex) {
                        container.insertBefore(this.draggedElement, e.target.nextSibling);
                    } else {
                        container.insertBefore(this.draggedElement, e.target);
                    }
                }
            }
        }
        
        // 初始化应用
        document.addEventListener('DOMContentLoaded', () => {
            new TennisCourtCustomizer();
        });
    </script>
</body>
</html>